;================================================================
;  delay.s
;               Delay with one clock accuracy
;
;================================================================
;
; 25thanni, a demo dedicated to the 25th anniversary of the ZX81.
;
; (c)2006 Bodo Wenzel
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation; either version 2 of
; the License, or (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with this program; if not, write to the Free
; Software Foundation Inc., 59 Temple Place, Suite 330, Boston,
; MA 02111-1307 USA
;================================================================

	.module	delay

;= Constants ====================================================

DELAY_OFFSET	==	-144

;= Program code =================================================

	.area	CODE

;- Delays with one clock accuracy -------------------------------
; A	number_of_clocks + DELAY_OFFSET
; (Look, Minas, no self modifying code and no other registers ;-)
; Credits to Minas to make such a routine thinkable, and thanks
; for the trick around the 16-clocks-loop!

delay::				; 17 (for call)

	rrca			; 4
	jr	c,d_xxx1	; 12 / 7
	ld	a,a		; 4
d_xxx1:				; xxx0: 15, xxx1: 16

	rrca			; 4
	jr	c,.+2		; 12 / 7
	jr	c,d_xx1x	; 12 / 7
	ld	a,a		; 4
	ld	a,a		; 4
d_xx1x:				; xx0x: 26, xx1x: 28

	rrca			; 4
	jr	c,.+2		; 12 / 7
	jr	c,.+2		; 12 / 7
	jr	c,d_x1xx	; 12 / 7
	ld	a,a		; 4
	add	a,#0		; 7
d_x1xx:				; x0xx: 36, x1xx: 40

	rrca			; 4
	jr	c,.+2		; 12 / 7
	jr	c,.+2		; 12 / 7
	jr	c,d_1xxx	; 12 / 7
	add	a,#0		; 7
d_1xxx:				; 0xxx: 32, 1xxx: 40

	and	#0x0F		; 7
	ret	z		; 11 / 5
				; missing 6 clocks if not zero

d_loop:
	dec	a		; 4
	jr	nz,d_loop	; 12 / 7
				; missing 5 clocks for last
	ret	z		; 11 (ret has 10 clocks)

;= The end ======================================================
